#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# Copyright (c) 2021, Jeff McBride
#
# This file is part of the modm project.
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
# -----------------------------------------------------------------------------

def _get_properties(env, instance=None):
    device = env[":target"]
    peripheral = "Flexcom" if device.has_driver("flexcom") else "Usart"
    return {
        "type" : "usart",
        "peripheral" : peripheral,
        "id" : instance,
        "prefix" : "US",
        "sr" : "CSR",
        "target" : device.identifier
    }


class Instance(Module):
    def __init__(self, driver, instance):
        self.driver = driver
        self.instance = int(instance)

    def init(self, module):
        module.name = str(self.instance)
        module.description = "Instance {}".format(self.instance)

    def prepare(self, module, options):
        module.depends(":platform:usart")

        module.add_option(
            NumericOption(
                name="buffer.tx",
                description="Size of transmit buffer",
                minimum=1, maximum=2 ** 16 - 2,
                default=64))
        module.add_option(
            NumericOption(
                name="buffer.rx",
                description="Size of receive buffer",
                minimum=1, maximum=2 ** 16 - 2,
                default=64))

        return True

    def build(self, env):
        env.substitutions = _get_properties(env, self.instance)
        env.outbasepath = "modm/src/modm/platform/usart"

        env.template("../uart.hpp.in", "usart_{}.hpp".format(self.instance))
        env.template("../uart.cpp.in", "usart_{}.cpp".format(self.instance))


def init(module):
    module.name = ":platform:usart"
    module.description = "Universal Synchronous Asynchronous Receiver Transmitter (USART)"


def prepare(module, options):
    device = options[":target"]
    if (not device.has_driver("usart:sam*")) or device.has_driver("sercom:sam"):
        return False

    module.depends(
        ":architecture:uart",
        ":math:algorithm",
        ":cmsis:device",
        ":platform:gpio",
        ":platform:clockgen")

    drivers = options[":target"].get_all_drivers("usart")
    for driver in drivers:
        for instance in driver["instance"]:
            module.add_submodule(Instance(driver, instance))

    return True


def build(env):
    env.substitutions = _get_properties(env)
    env.outbasepath = "modm/src/modm/platform/usart"
    env.template("../uart_base.hpp.in", "usart_base.hpp")
